﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TestMySqlConnetPoll
{
    public struct objSendDailyCurveTime //本次调取日曲线的时间
    {
        public int stime;   //开始时间
        public int etime;   //结束时间
    }
    public static class c_TerminalOperation     //终端操作类
    {
        
        /// <summary>
        /// 调取日曲线的保持数据.
        /// </summary>
        ///public static objSendDailyCurveTime SendDailyCurveTime = new objSendDailyCurveTime();
        private static string ExtractDailyCurveCsmStr = ""; //最近一次发送的模拟量日曲线设备类型名
        private static string ExtractDailyCurveDevstr = ""; //最近一次发送的模拟量日曲线设备名
        private static string ExtractDailyCurveAttriStr = "";//属性名
        private static objDate ExtractDailyCurveDay = new objDate(); //最近一次发送的模拟量日曲线日期

        /// <summary>
        /// 调取高频日曲线的保持数据.
        /// </summary>
        ///public static objSendDailyCurveTime SendDailyCurveTime = new objSendDailyCurveTime();
        private static string ExtractHigDailyCurveCsmStr = ""; //最近一次发送的模拟量日曲线设备类型名
        private static string ExtractHigDailyCurveDevstr = ""; //最近一次发送的模拟量日曲线设备名
        private static string ExtractHigDailyCurveAttriStr = "";//属性名
        private static objDate ExtractHigDailyCurveDay;         //最近一次发送的模拟量日曲线日期

        private static int ExtractKglReplayStime = 0;     //最近一次调取开关量的开始时间
        private static int ExtractKglReplayEtime = 0;     //最近一次调取开个量的结束时间
        private static int UserSelectRecallNum = 0;       //用户选择的回放时间段
        
        /// <summary>
        /// 终端提取模拟量实时值命令，按照设备类型提取，如果一种设备类型有5种类型的模拟量，则发5次命令,每次提取一种模拟量类型的实时数据
        /// 用于打开实时值表格时的数据填充
        /// </summary>
        /// <param name="CsmDevName"></param> 设备类型名称
        public static void SendExtractAnalogRealTimeValue(string CsmDevName)
        {
            List<byte> AnalogType = new List<byte>();
            if (c_Device.DeviceMsgGather.ContainsKey(CsmDevName))
            {
                objMsgGatherStruct obj = c_Device.DeviceMsgGather[CsmDevName];
                foreach(objMsgAttriStruct o in obj.ArrtiList)
                {
                    byte t = (byte) o.AnalogType;
                    if (AnalogType.Contains(t)) { }
                    else AnalogType.Add(t);
                }
                for (int i = 0; i < AnalogType.Count; i++)
                {
                    string dcode = c_Config.sysConfig.TelexCode;
                    c_NetCom.CmdSendOneTypeAnalogRealTimeValue(dcode, AnalogType[i]);   //一次把所有的命令发送完全.
                }
            }
        }
        /// <summary>
        /// 提取特定模拟量实时值数据，依据设备的属性来提取
        /// 用于实时曲线数据调取，周期1S一次
        /// </summary>
        /// <param name="CsmDevName"></param>  设备类型名称
        /// <param name="DevName"></param>设备名称
        /// <param name="AttriName"></param>属性集合
        public static void SendExtractSpecialAnalogRealTimeValue(string CsmDevName, string DevName, List<string> AttriName)
        {
            if (c_Device.DeviceMsgGather.ContainsKey(CsmDevName))
            {
                objMsgGatherStruct obj = c_Device.DeviceMsgGather[CsmDevName];
                objMsgDevStruct objDev = new objMsgDevStruct();
                List<AnalogObj> di = new List<AnalogObj>();
                for (int i = 0; i < obj.DevList.Count; i++)
                {
                    if (obj.DevList[i].DevName == DevName)
                    {
                        objDev = obj.DevList[i];
                    }
                }
                foreach(string key in AttriName)
                {
                    for (int i = 0; i < obj.ArrtiList.Count; i++)
                    {
                        if (key == obj.ArrtiList[i].AttriName)
                        {
                            AnalogObj a = new AnalogObj();
                            a.type = obj.ArrtiList[i].AnalogType;
                            if (a.type != AnalogCodeType.None)
                            {
                                if (i < objDev.AnalogSet.Count)
                                {
                                    a.devNo = objDev.AnalogSet[i];
                                    di.Add(a);
                                    break;
                                }
                            }
                        }
                    }
                }
                string dcode = c_Config.sysConfig.TelexCode;
                if (di.Count > 0)
                {
                    c_NetCom.CmdSendSpecifiedAnalogRealTime(dcode, di);   //发送提取特定模拟量实时值的命令
                }
            }
        }
        /// <summary>
        /// 终端提取模拟量最新值数据，一般指绝缘、漏流、残压的最新值
        /// </summary>
        /// <param name="CsmDevName"></param>
        public static void SendExtractNewstRealTimeValue(string CsmDevName)
        {
            byte type = 0;
            if (CsmDevName.Contains("绝缘")) type = 0x80;
            else if (CsmDevName.Contains("漏流")) type = 0x81;
            else if (CsmDevName.Contains("残压")) type = 0x24;
            string dcode = c_Config.sysConfig.TelexCode;
            c_NetCom.CmdSendAnalogNewstValue(dcode, type);
        }
        #region 日曲线操作
        /// <summary>
        /// 提取日报表时间命令，跟设备类型什么的都无关,一种设备类型只取一次
        /// </summary>
        /// <param name="CsmDevName"></param>
        public static void SendExtractDailyReportTimeList(string CsmDevName)
        {
            c_NetData.DailyReportTimeList.Clear();  //获取前清除时间列表
            byte type = 0;
            if (c_Device.DeviceMsgGather.ContainsKey(CsmDevName))
            {
                objMsgGatherStruct obj = c_Device.DeviceMsgGather[CsmDevName];
                for(int i = 0;i<obj.ArrtiList.Count;i++)
                {
                    if(obj.ArrtiList[i].AnalogType!=AnalogCodeType.None)
                    {
                        type = (byte)obj.ArrtiList[i].AnalogType;
                        string dcode = c_Config.sysConfig.TelexCode;
                        c_NetCom.CmdSendDailyReportTime(dcode, type);
                    }
                }                
            }            
        }
        /// <summary>
        /// 发送提取日报表数据命令，按照设备类型，如果一种设备类型有多个模拟量类型，则发送多次命令
        /// </summary>
        /// <param name="CsmDevName"></param>
        /// <param name="date"></param>
        public static void SendExtractDailyReportData(string CsmDevName, objDate date)
        {
            c_NetData.DailyReportAnalogValueList.Clear();
            if (c_Device.DeviceMsgGather.ContainsKey(CsmDevName))
            {
                List<byte> li = new List<byte>();
                string dcode = c_Config.sysConfig.TelexCode;
                objMsgGatherStruct obj = c_Device.DeviceMsgGather[CsmDevName];
                foreach (objMsgAttriStruct key in obj.ArrtiList)
                {
                    if (key.AnalogType != AnalogCodeType.None)
                    {
                        li.Add((byte)key.AnalogType);
                    }
                }
                DateTime t = new DateTime(date.year, date.month, date.day, 0, 0, 0);
                int ut = (int)MySql.DateTimeToTime_t(t);
                for (int i = 0; i < li.Count; i++)
                {
                    c_NetCom.CmdSendDailyReportValue(dcode, li[i], ut);
                }
            }
        }
        /// <summary>
        /// 发送提取日曲线时间命令
        /// </summary>
        /// <param name="CsmDevName"></param>
        public static void SendExtractDailyCurveTimeList(string CsmDevName)
        {
            c_NetData.DailyCurveTimeList.Clear();  //获取前清除时间列表
            byte type = 0;
            if (c_Device.DeviceMsgGather.ContainsKey(CsmDevName))
            {
                objMsgGatherStruct obj = c_Device.DeviceMsgGather[CsmDevName];
                for (int i = 0; i < obj.ArrtiList.Count; i++)
                {
                    if (obj.ArrtiList[i].AnalogType != AnalogCodeType.None)
                    {
                        type = (byte)obj.ArrtiList[i].AnalogType;
                        string dcode = c_Config.sysConfig.TelexCode;
                        c_NetCom.CmdSendAnalogDailyCurveTime(dcode, type);
                    }
                }
            }
        }

        /// <summary>
        /// 检查日曲线缓冲区内是否有数据，掉日曲线时首先需调用该函数
        /// 返回：
        /// 0 无数据
        /// 1 有回溯数据，使用回溯命令
        /// 2 有可用数据，直接取缓冲区内数据。
        /// </summary>
        /// <param name="CsmDevName"></param>
        /// <param name="DevName"></param>
        /// <param name="AttriName"></param>
        /// <param name="time"></param>
        /// <param name="am">上午标志</param>
        /// <returns></returns>
        public static int CheckDailyCurveData(string CsmDevName, string DevName, string AttriName, objDate time, bool am)
        {
            objDate tmpDate = time;
            if (tmpDate.day != c_NetData.TerminalDailyCurveDay.day || tmpDate.month != c_NetData.TerminalDailyCurveDay.month 
                || tmpDate.year != c_NetData.TerminalDailyCurveDay.year)
            {
                c_NetData.TerminalDailyCurveDay = tmpDate;
                c_NetData.TermianlAmDailyCurveValueList.Clear();
                c_NetData.TermianlPmDailyCurveValueList.Clear();
                c_NetData.TerminalDailyAmCurveRecallTime.rNum = 0;
                c_NetData.TerminalDailyPmCurveRecallTime.rNum = 0;
                return 0;   //缓冲区内没有值
            }
            AnalogObj obj = c_Device.GetAnalogDevNo(CsmDevName, DevName, AttriName);
            objCodeDev cd = new objCodeDev();
            cd.codetype = (byte)obj.type;
            cd.dev_no = (short)obj.devNo;
            if (am)  //上午
            {
                if (c_NetData.TerminalDailyAmCurveRecallTime.rNum != 0)
                {
                    c_NetData.TermianlAmDailyCurveValueList.Clear();
                    return 1;   //有回溯数据
                }
                else if (c_NetData.TermianlAmDailyCurveValueList.Keys.Contains(cd))
                {
                    return 2;   //缓冲区内有数据
                }
                else return 0;  //无数据
            }
            else    //下午
            {
                if (c_NetData.TerminalDailyPmCurveRecallTime.rNum != 0)
                {
                    c_NetData.TermianlPmDailyCurveValueList.Clear();
                    return 1;   //有回溯数据
                }
                else if (c_NetData.TermianlPmDailyCurveValueList.Keys.Contains(cd))
                {
                    return 2;   //缓冲区内有数据
                }
                else return 0;  //无数据
            }
        }

        ///日曲线调用流程
        ///首先调用CheckDailyCurveData 检查缓冲区
        ///1.首先检查是否有回溯时间段的记录（该记录为站机发送过来的，如果当前调用了一条日曲线，则该记录都保持）
        ///2.有回溯时间段记录，如果有上午的回溯时间，则弹出对话框，让用户选择好哪段时间段；根据用户选择的时间段发送提取上午回溯数据命令,再判断发送提取下午数据段命令。
        ///3.判断下午是否有回溯时间.有回溯时间则让用户选择时间段，后再发送提取回溯数据命令，下午没有回溯时间，则直接发送提取下午数据
        ///一天上午下午分别提取，两个回溯时间命令.
        ///有回溯的，都清除缓冲区数据
        ///没有回溯的，则首先到缓冲区内去找，找到了则不再向站机发送命令.
        /// <summary>
        /// 发送提取器曲线命令,上午的数据
        /// 一条日曲线分两次调用，按照协议，一次的点数不够协议数
        /// </summary>
        /// <param name="CsmDevName"></param>
        /// <param name="DevName"></param>
        /// <param name="AttriName"></param>
        /// <param name="time"></param>
        public static void SendExtractDailyCurveAM_Data(string CsmDevName, string DevName, string AttriName, objDate time)
        {
            ///以下为取半天的数据，如果站机回执是填充数据的，则需要分两次发送命令
            string dcode = c_Config.sysConfig.TelexCode;
            AnalogObj obj = c_Device.GetAnalogDevNo(CsmDevName, DevName, AttriName);
            DateTime t = new DateTime(time.year, time.month, time.day, 0, 0, 0);
            int stime = (int)MySql.DateTimeToTime_t(t);
            DateTime et = new DateTime(time.year, time.month, time.day, 11, 59, 59);
            int etime = (int)MySql.DateTimeToTime_t(et);
            c_NetCom.CmdSendAnalogDailyCurve(dcode, (byte)obj.type, (short)obj.devNo, stime, etime);    //先取半天的数据，再取半天的数据 

            ExtractDailyCurveCsmStr = CsmDevName;   //最近一次发送的模拟量日曲线设备类型名
            ExtractDailyCurveDevstr = DevName;      //最近一次发送的模拟量日曲线设备名
            ExtractDailyCurveAttriStr = AttriName;
            ExtractDailyCurveDay = time;            //最近一次发送的模拟量日曲线日期
        }

        /// <summary>
        /// 发送提取曲线命令，下午的数据
        /// </summary>
        /// <param name="CsmDevName"></param>
        /// <param name="DevName"></param>
        /// <param name="AttriName"></param>
        /// <param name="time"></param>
        public static void SendExtractDailyCurvePM_Data(string CsmDevName, string DevName, string AttriName, objDate time)
        {
            string dcode = c_Config.sysConfig.TelexCode;
            AnalogObj obj = c_Device.GetAnalogDevNo(CsmDevName, DevName, AttriName);
            DateTime t2 = new DateTime(time.year, time.month, time.day, 12, 0, 0);
            int st2 = (int)MySql.DateTimeToTime_t(t2);
            DateTime ed2 = new DateTime(time.year, time.month, time.day, 23, 59, 59);
            int et2 = (int)MySql.DateTimeToTime_t(ed2);
            c_NetCom.CmdSendAnalogDailyCurve(dcode, (byte)obj.type, (short)obj.devNo, st2, et2);    //先取半天的数据，再取半天的数据            
        }

        /// <summary>
        /// 发送提取回溯时间段命令
        /// 如果是自己检测到有回溯时间段的数据，让用户选择后，直接调用该函数,传入的参数，是用户点击的参数
        /// 否则在站机回执了回溯时间段的数据是，用户选择后，调用该函数，传入的参数是最后一次调用日曲线的参数，
        /// ExtractDailyCurveCsmStr = CsmDevName;   //最近一次发送的模拟量日曲线设备类型名
        /// ExtractDailyCurveDevstr = DevName;      //最近一次发送的模拟量日曲线设备名
        /// ExtractDailyCurveAttriStr = AttriName;
        /// ExtractDailyCurveDay = time;            //最近一次发送的模拟量日曲线日期
        /// </summary>
        /// <param name="rNum"></param>
        /// <param name="type"></param>
        /// <param name="devNo"></param>
        /// <param name="time"></param>
        public static void SendExtractDailyCurveDataRecall(int rNum, string CsmDevName, string DevName, string AttriName, objDate time)
        {
            AnalogObj obj = c_Device.GetAnalogDevNo(CsmDevName, DevName, AttriName);
            byte type = (byte)obj.type;
            short devNo = (short)obj.devNo;
            if (c_NetData.TerminalDailyAmCurveRecallTime.rNum != 0)     //上午的回溯时间命令
            {
                string dcode = c_Config.sysConfig.TelexCode;
                DateTime t = new DateTime(time.year, time.month, time.day, 0, 0, 0);
                int stime = (int)MySql.DateTimeToTime_t(t);
                DateTime et = new DateTime(time.year, time.month, time.day, 11, 59, 59);
                int etime = (int)MySql.DateTimeToTime_t(et);
                int rstime = c_NetData.TerminalDailyAmCurveRecallTime.srecalltime;
                int estime = c_NetData.TerminalDailyAmCurveRecallTime.erecalltime;
                c_NetCom.CmdSendAnalogHistoryCurveRecallTime(dcode, type, (short)devNo, stime, etime, rNum, rstime, estime);
            }
            else if (c_NetData.TerminalDailyPmCurveRecallTime.rNum != 0)    //下午的回溯时间命令
            {
                string dcode = c_Config.sysConfig.TelexCode;
                DateTime t = new DateTime(time.year, time.month, time.day, 0, 0, 0);
                int stime = (int)MySql.DateTimeToTime_t(t);
                DateTime et = new DateTime(time.year, time.month, time.day, 11, 59, 59);
                int etime = (int)MySql.DateTimeToTime_t(et);
                int rstime = c_NetData.TerminalDailyPmCurveRecallTime.srecalltime;
                int estime = c_NetData.TerminalDailyPmCurveRecallTime.erecalltime;
                c_NetCom.CmdSendAnalogHistoryCurveRecallTime(dcode, type, (short)devNo, stime, etime, rNum, rstime, estime);
            }
        }
        #endregion
        #region 高频日曲线操作 半自闭
        /// <summary>
        /// 检查高频日曲线缓冲区内是否有数据，调高频日曲线时首先需调用该函数
        /// 返回：
        /// 0 无数据
        /// 1 有回溯数据，使用回溯命令
        /// 2 有可用数据，直接取缓冲区内数据。
        /// </summary>
        /// <param name="CsmDevName"></param>
        /// <param name="DevName"></param>
        /// <param name="AttriName"></param>
        /// <param name="time"></param>
        /// <param name="am">上午标志</param>
        /// <returns></returns>
        public static int CheckDailyHighFrequencyCurveData(string CsmDevName, string DevName, string AttriName, objDate time, bool am)
        {
            objDate tmpDate = time;
            if (tmpDate.day != c_NetData.TerminalDailyHigCurveDay.day || tmpDate.month != c_NetData.TerminalDailyHigCurveDay.month 
                || tmpDate.year != c_NetData.TerminalDailyHigCurveDay.year)
            {
                c_NetData.TerminalDailyHigCurveDay = tmpDate;
                c_NetData.TermianlAmDailyHigCurveValueList.Clear();
                c_NetData.TermianlPmDailyHigCurveValueList.Clear();
                c_NetData.TerminalDailyAmHigCurveRecallTime.rNum = 0;
                c_NetData.TerminalDailyPmHigCurveRecallTime.rNum = 0;
                return 0;   //缓冲区内没有值
            }
            AnalogObj obj = c_Device.GetAnalogDevNo(CsmDevName, DevName, AttriName);
            objCodeDev cd = new objCodeDev();
            cd.codetype = (byte)obj.type;
            cd.dev_no = (short)obj.devNo;
            if (am)  //上午
            {
                if (c_NetData.TerminalDailyAmHigCurveRecallTime.rNum != 0)
                {
                    c_NetData.TermianlAmDailyHigCurveValueList.Clear();
                    return 1;   //有回溯数据
                }
                else if (c_NetData.TermianlAmDailyHigCurveValueList.Keys.Contains(cd))
                {
                    return 2;   //缓冲区内有数据
                }
                else return 0;  //无数据
            }
            else    //下午
            {
                if (c_NetData.TerminalDailyPmHigCurveRecallTime.rNum != 0)
                {
                    c_NetData.TermianlPmDailyHigCurveValueList.Clear();
                    return 1;   //有回溯数据
                }
                else if (c_NetData.TermianlPmDailyHigCurveValueList.Keys.Contains(cd))
                {
                    return 2;   //缓冲区内有数据
                }
                else return 0;  //无数据
            }
        }

        ///高频日曲线调用流程
        ///首先调用CheckDailyHighFrequencyCurveData 检查缓冲区
        ///1.首先检查是否有回溯时间段的记录（该记录为站机发送过来的，如果当前调用了一条日曲线，则该记录都保持）
        ///2.有回溯时间段记录，如果有上午的回溯时间，则弹出对话框，让用户选择好哪段时间段；根据用户选择的时间段发送提取上午回溯数据命令,再判断发送提取下午数据段命令。
        ///3.判断下午是否有回溯时间.有回溯时间则让用户选择时间段，后再发送提取回溯数据命令，下午没有回溯时间，则直接发送提取下午数据
        ///一天上午下午分别提取，两个回溯时间命令.
        ///有回溯的，都清除缓冲区数据
        ///没有回溯的，则首先到缓冲区内去找，找到了则不再向站机发送命令.
        /// <summary>
        /// 发送提取器曲线命令,上午的数据
        /// 一条日曲线分两次调用，按照协议，一次的点数不够协议数
        /// </summary>
        /// <param name="CsmDevName"></param>
        /// <param name="DevName"></param>
        /// <param name="AttriName"></param>
        /// <param name="time"></param>
        public static void SendExtractDailyHighCurveAM_Data(string CsmDevName, string DevName, string AttriName, objDate time)
        {
            ///以下为取半天的数据，如果站机回执是填充数据的，则需要分两次发送命令
            string dcode = c_Config.sysConfig.TelexCode;
            AnalogObj obj = c_Device.GetAnalogDevNo(CsmDevName, DevName, AttriName);
            DateTime t = new DateTime(time.year, time.month, time.day, 0, 0, 0);
            int stime = (int)MySql.DateTimeToTime_t(t);
            DateTime et = new DateTime(time.year, time.month, time.day, 11, 59, 59);
            int etime = (int)MySql.DateTimeToTime_t(et);
            c_NetCom.CmdSendHighFrequencyAnalog(dcode, (byte)obj.type, (short)obj.devNo, stime, etime);    //先取半天的数据，再取半天的数据 

            ExtractHigDailyCurveCsmStr = CsmDevName;   //最近一次发送的模拟量日曲线设备类型名
            ExtractHigDailyCurveDevstr = DevName;      //最近一次发送的模拟量日曲线设备名
            ExtractHigDailyCurveAttriStr = AttriName;
            ExtractHigDailyCurveDay = time;            //最近一次发送的模拟量日曲线日期
        }

        /// <summary>
        /// 发送提取高频曲线命令，下午的数据
        /// </summary>
        /// <param name="CsmDevName"></param>
        /// <param name="DevName"></param>
        /// <param name="AttriName"></param>
        /// <param name="time"></param>
        public static void SendExtractDailyHighCurvePM_Data(string CsmDevName, string DevName, string AttriName, objDate time)
        {
            string dcode = c_Config.sysConfig.TelexCode;
            AnalogObj obj = c_Device.GetAnalogDevNo(CsmDevName, DevName, AttriName);
            DateTime t2 = new DateTime(time.year, time.month, time.day, 12, 0, 0);
            int st2 = (int)MySql.DateTimeToTime_t(t2);
            DateTime ed2 = new DateTime(time.year, time.month, time.day, 23, 59, 59);
            int et2 = (int)MySql.DateTimeToTime_t(ed2);
            c_NetCom.CmdSendHighFrequencyAnalog(dcode, (byte)obj.type, (short)obj.devNo, st2, et2);    //先取半天的数据，再取半天的数据            
        }

        /// <summary>
        /// 发送提取高频回溯时间段命令
        /// 如果是自己检测到有回溯时间段的数据，让用户选择后，直接调用该函数,传入的参数，是用户点击的参数
        /// 否则在站机回执了回溯时间段的数据是，用户选择后，调用该函数，传入的参数是最后一次调用日曲线的参数，
        /// ExtractHigDailyCurveCsmStr = CsmDevName;   //最近一次发送的模拟量日曲线设备类型名
        /// ExtractHigDailyCurveDevstr = DevName;      //最近一次发送的模拟量日曲线设备名
        /// ExtractHigDailyCurveAttriStr = AttriName;
        /// ExtractHigDailyCurveDay = time;            //最近一次发送的模拟量日曲线日期
        /// </summary>
        /// <param name="rNum"></param>
        /// <param name="type"></param>
        /// <param name="devNo"></param>
        /// <param name="time"></param>
        public static void SendExtractDailyHighCurveDataRecall(int rNum, string CsmDevName, string DevName, string AttriName, objDate time)
        {
            AnalogObj obj = c_Device.GetAnalogDevNo(CsmDevName, DevName, AttriName);
            byte type = (byte)obj.type;
            short devNo = (short)obj.devNo;
            if (c_NetData.TerminalDailyAmHigCurveRecallTime.rNum != 0)     //上午的回溯时间命令
            {
                string dcode = c_Config.sysConfig.TelexCode;
                DateTime t = new DateTime(time.year, time.month, time.day, 0, 0, 0);
                int stime = (int)MySql.DateTimeToTime_t(t);
                DateTime et = new DateTime(time.year, time.month, time.day, 11, 59, 59);
                int etime = (int)MySql.DateTimeToTime_t(et);
                int rstime = c_NetData.TerminalDailyAmHigCurveRecallTime.srecalltime;
                int estime = c_NetData.TerminalDailyAmHigCurveRecallTime.erecalltime;
                c_NetCom.CmdSendHighFrequencyRecallTime(dcode, type, (short)devNo, stime, etime, rNum, rstime, estime);
            }
            else if (c_NetData.TerminalDailyPmHigCurveRecallTime.rNum != 0)    //下午的回溯时间命令
            {
                string dcode = c_Config.sysConfig.TelexCode;
                DateTime t = new DateTime(time.year, time.month, time.day, 0, 0, 0);
                int stime = (int)MySql.DateTimeToTime_t(t);
                DateTime et = new DateTime(time.year, time.month, time.day, 11, 59, 59);
                int etime = (int)MySql.DateTimeToTime_t(et);
                int rstime = c_NetData.TerminalDailyPmHigCurveRecallTime.srecalltime;
                int estime = c_NetData.TerminalDailyPmHigCurveRecallTime.erecalltime;
                c_NetCom.CmdSendHighFrequencyRecallTime(dcode, type, (short)devNo, stime, etime, rNum, rstime, estime);
            }
        }
        #endregion

        #region 回放数据提取
        ///回放数据提取流程
        ///1.首先提取开关量时间表
        ///2.用户选择回放段时间后，首先发送开关量提取数据
        ///3.等待站机回执开关量数据，如果有回溯,用户选择后，则发送提取开关量回溯命令，
        ///4.如果有回溯，发送提取模拟量回放命令，无回溯，直接发送提取模拟量命令
        /// <summary>
        /// 提取开关量回放时间
        /// </summary>
        public static void SendExtractKglTimeList()
        {
            string dcode = c_Config.sysConfig.TelexCode;
            c_NetCom.CmdSendKGLReplayTime(dcode);
        }

        public static void SendExtractKglReplayData(int stime, int etime)
        {
            ExtractKglReplayStime = stime;
            ExtractKglReplayEtime = etime;
            string dcode = c_Config.sysConfig.TelexCode;
            c_NetCom.CmdGetKGLReplayData(dcode, stime, etime);
        }
        /// <summary>
        /// 提取开关量回溯时间段数据
        /// 开始时间和结束时间取自上次发送的开始时间和结束时间。
        /// 回溯时间段取自从站机接收到的回溯时间段。
        /// 设备索引号无意义
        /// </summary>
        /// <param name="stime"></param>开始时间
        /// <param name="etime"></param>结束时间
        /// <param name="rNum"></param>重复序号 用户选择
        /// <param name="rstime"></param>重复开始时间
        /// <param name="retime"></param>重复结束时间
        /// <param name="DevNo"></param>设备索引号
        public static void SendExtractKglReplayRecallData(int rNum)
        {
            string dcode = c_Config.sysConfig.TelexCode;
            int stime = ExtractKglReplayStime;
            int etime = ExtractKglReplayEtime;
            int rstime = c_NetData.KGLRecallStime;
            int retime= c_NetData.KGLRecallEtime;
            c_NetCom.CmdGetKGLRecallData(dcode, 0, stime, etime, rNum, rstime, retime);
            UserSelectRecallNum = rNum;
        }
        /// <summary>
        /// 提取模拟量回放记录
        /// </summary>
        /// <param name="stime"></param>
        /// <param name="etime"></param>
        /// <param name="AnalogNum"></param>模拟量类型数目
        /// <param name="AnalogSet"></param>模拟量类型集合
        public static void SendExtractAnalogReplayData(int stime, int etime, int AnalogNum, List<byte> AnalogSet=null)
        {
            string dcode = c_Config.sysConfig.TelexCode;
            c_NetCom.CmdSendAnalogReplayData(dcode, stime, etime, (byte)AnalogNum, AnalogSet);
        }
        /// <summary>
        /// 用户选择的回溯段回放时间
        /// 只支持取该时间段的所有模拟量，协议中的设备索引号，其实无效.
        /// </summary>
        public static void SendExtractAnalogReplayRecallData()
        {
            string dcode = c_Config.sysConfig.TelexCode;
            int stime = ExtractKglReplayStime;
            int etime = ExtractKglReplayEtime;
            int rstime = c_NetData.KGLRecallStime;
            int retime = c_NetData.KGLRecallEtime;
            int rNum = UserSelectRecallNum;     //用户选择的回溯段数据
            c_NetCom.CmdSendAnalogReplayRecall(dcode, 0xff, stime, etime, rNum, rstime, retime);
        }
        /// <summary>
        /// 发送提取高频模拟量回放数据
        /// </summary>
        /// <param name="stime"></param>
        /// <param name="etime"></param>
        /// <param name="AnalogNum"></param>
        /// <param name="AnalogSet"></param>
        public static void SendExtractHighFrequencyReplayData(int stime, int etime, int AnalogNum, List<byte> AnalogSet = null)
        {
            string dcode = c_Config.sysConfig.TelexCode;
            c_NetCom.CmdSendHighFrequencyReplay(dcode, stime, etime, (byte)AnalogNum, AnalogSet);
        }
        /// <summary>
        /// 发生提取高频模拟量回复时间段数据
        /// </summary>
        public static void SendExtractHighFrequencyReplayRecallData()
        {
            string dcode = c_Config.sysConfig.TelexCode;
            int stime = ExtractKglReplayStime;
            int etime = ExtractKglReplayEtime;
            int rstime = c_NetData.KGLRecallStime;
            int retime = c_NetData.KGLRecallEtime;
            int rNum = UserSelectRecallNum;     //用户选择的回溯段数据
            c_NetCom.CmdSendHighFrequencyReplayRecall(dcode, 0xff, stime, etime, rNum, rstime, retime);
        }
        #endregion
        /// <summary>
        /// 请求全体开关量状态
        /// </summary>
        public static void ExtractRealTimeKGL()
        {
            c_NetCom.AutoSendKGLALLRealTimeData();
        }
        /// <summary>
        /// 提取开关量历史数据
        /// </summary>
        /// <param name="stime"></param>
        /// <param name="etime"></param>
        public static void SendExtractKglHistoryData(int stime, int etime)
        {            
            string dcode = c_Config.sysConfig.TelexCode;
            c_NetCom.CmdSendKglData(dcode, stime, etime);
        }
        /// <summary>
        /// 提取记录型曲线时间列表信息
        /// </summary>
        /// <param name="CurveType"></param>类型名称
        /// <param name="DevStr"></param> 设备名称
        public static void SendExtractRecordCurveTimeList(string CurveType, string DevStr)
        {
            c_NetData.TerminalRecordCurveTimeList.Clear();
            string dcode = c_Config.sysConfig.TelexCode;
            int type = 0;
            int devNo = 0;
            if (CurveType.Contains("道岔动作曲线"))
            {
                type = 0x10;
                devNo = c_Device.GetDcdlqxDevNo(DevStr);
            }
            else if (CurveType.Contains("道岔油压"))
            {
                type = 0x11;
            }
            else if (CurveType.Contains("道岔拉力"))
            {
                type = 0x12;
            }
            else if (CurveType.Contains("高压不对称"))
            {
                type = 0x13;
                devNo = c_Device.GetGybdcDyDevNo(DevStr);
            }
            c_NetCom.CmdSendRecordCurveTime(dcode, (byte)type, devNo);
        }
        /// <summary>
        /// 发送提取记录曲线数据命令
        /// </summary>
        /// <param name="CurveType"></param>
        /// <param name="DevStr"></param>
        /// <param name="t"></param>
        public static void SendExtractRecordCurveValue(string CurveType, string DevStr, DateTime t)
        {
            string dcode = c_Config.sysConfig.TelexCode;
            int type = 0;
            int devNo = 0;
            if (CurveType.Contains("道岔动作曲线"))
            {
                type = 0x10;
                devNo = c_Device.GetDcdlqxDevNo(DevStr);
            }
            else if (CurveType.Contains("道岔油压"))
            {
                type = 0x11;
            }
            else if (CurveType.Contains("道岔拉力"))
            {
                type = 0x12;
            }
            else if (CurveType.Contains("高压不对称"))
            {
                type = 0x13;
                devNo = c_Device.GetGybdcDyDevNo(DevStr);
            }


            int ut = (int)MySql.DateTimeToTime_t(t);

            objRecordCurveKey key = new objRecordCurveKey();
            key.DevNo = devNo;
            key.DevType = (byte)type;
            key.time = t;
            if (c_NetData.TerminalDcdlqxValueList.Keys.Contains(key) || c_NetData.TerminalGybdcValueList.Keys.Contains(key))
            { }
            else
            {
                c_NetCom.CmdSendRecordCurve(dcode, (byte)type, devNo, ut);
            }
        }
        /// <summary>
        /// 终端查询空调参数
        /// </summary>
        public static void SendExtractAirConditionParameter()
        {
            string dcode = c_Config.sysConfig.TelexCode;
            c_NetCom.CmdSendQueryAirConditionInfo(dcode);
        }
        /// <summary>
        /// 终端修改空调参数
        /// </summary>
        public static void SendModifyAirConditionParamenter()
        {
            string dcode = c_Config.sysConfig.TelexCode;
        }
        /// <summary>
        /// 终端控制空调命令
        /// </summary>
        public static void SendControlAirConditon()
        {
            string dcode = c_Config.sysConfig.TelexCode;
        }
        /// <summary>
        /// 终端发送提取统计信息命令
        /// </summary>
        /// <param name="TongJiType"></param>
        /// <param name="time"></param>
        public static void SendExtractTongJiTime(string TongJiType,DateTime time)
        {
            string dcode = c_Config.sysConfig.TelexCode;
            int type = c_Device.GetTongJiType(TongJiType);
            int year = time.Year;
            for (int i = 0; i < 12; i++)
            {
                DateTime t = new DateTime(year, i + 1, 1);
                c_NetCom.CmdSendStatisticsTime(dcode, (byte)type, (int)MySql.DateTimeToTime_t(time));
            }
        }
        /// <summary>
        /// 发送获取报警时间列表命令
        /// </summary>
        /// <param name="alarmTypeName"></param>
        public static void SendExtractAlarmTimeList(string alarmTypeName)
        {
            string dcode = c_Config.sysConfig.TelexCode;
            int type = c_Device.GetAlarmTypeCode(alarmTypeName);
            c_NetCom.CmdDevAlarmTimeList(dcode, (byte)type);
        }
        /// <summary>
        /// 发送获取历史报警命令
        /// </summary>
        /// <param name="alarmTypeName"></param>
        /// <param name="t"></param>
        public static void SendExtractAlarmValue(string alarmTypeName, DateTime t)
        {
            string dcode = c_Config.sysConfig.TelexCode;
            int type = c_Device.GetAlarmTypeCode(alarmTypeName);
            objDate d= MySql.DateTimeToobjDate(t);
            objHistoryAlaramKey key = new objHistoryAlaramKey();
            key.date = d;
            key.AlarmType = (byte)type;
            int stime = MySql.DateTimeToTime_t(new DateTime(t.Year,t.Month,t.Day,0,0,0));
            int etime = MySql.DateTimeToTime_t(new DateTime(t.Year,t.Month,t.Day,23,59,59));
            if (DateTime.Now.Year == t.Year && DateTime.Now.Month == t.Month && DateTime.Now.Day == t.Day)  //当天的都取数据，以免有新报警
            {
                if (c_NetData.TerminalAlarmValueList.Keys.Contains(key)) c_NetData.TerminalAlarmValueList.Remove(key);
                c_NetCom.CmdDevHistoryAlarm(dcode, (byte)type, stime, etime);
            }
            else
            {
                if (c_NetData.TerminalAlarmValueList.Keys.Contains(key)) { }  //在缓冲区内则不取数据
                else c_NetCom.CmdDevHistoryAlarm(dcode, (byte)type, stime, etime);
            }
        }
        /// <summary>
        /// 发送提取列控实时值命令，c2以上列控.
        /// </summary>
        /// <param name="LkType"></param>
        public static void SendExtractLKRealTime(string LkType)
        {
            string dcode = c_Config.sysConfig.TelexCode;
            if (LkType == "列控中心主机硬件平台")
            {
                int type = c_LK.GetLkProtecolNo("A机");
                if (type > 0)
                {
                    c_NetCom.CmdLk_C2RealTimeValue(dcode, 1, (byte)type);
                }
                type = c_LK.GetLkProtecolNo("B机");
                if (type > 0)
                {
                    c_NetCom.CmdLk_C2RealTimeValue(dcode, 1, (byte)type);
                }
            }
            else
            {
                int type = c_LK.GetLkProtecolNo(LkType);
                if (type > 0)
                {
                    c_NetCom.CmdLk_C2RealTimeValue(dcode, 1, (byte)type);
                }
            }
        }
        /// <summary>
        /// 发送提取列控时间命令，c2以上列控.
        /// </summary>
        /// <param name="LkType"></param>
        public static void SendExtractLKTimeList(string LkType)
        {
            c_NetData.TerminalLkHistoryEndTime = DateTime.MinValue;
            c_NetData.TerminalLkHistoryStartTime = DateTime.MinValue;
            string dcode = c_Config.sysConfig.TelexCode;
            if (LkType == "列控中心主机硬件平台")
            {
                int type = c_LK.GetLkProtecolNo("A机");
                if (type > 0)
                {
                    c_NetCom.CmdLk_C2TimeList(dcode, 1, (byte)type);
                }                
            }
            else
            {
                int type = c_LK.GetLkProtecolNo(LkType);
                if (type > 0)
                {
                    c_NetCom.CmdLk_C2TimeList(dcode, 1, (byte)type);
                }
            }
        }
        /// <summary>
        /// 发送提取列控历史数据命令
        /// </summary>
        /// <param name="LKType"></param>
        /// <param name="stime"></param>
        /// <param name="etime"></param>
        public static void SendExtractLkHistoryData(string LKType, DateTime stime, DateTime etime)
        {
            string dcode = c_Config.sysConfig.TelexCode;
            int type = -1;
            if (LKType == "列控中心主机硬件平台")
            {
                type = c_LK.GetLkProtecolNo("A机");                
            }
            else
            {
                type = c_LK.GetLkProtecolNo(LKType);
            }
            TimeSpan t = etime.Subtract(stime);
            if (t.TotalMinutes > 5) etime = stime.AddMinutes(5);    //最多5分钟
            if (type > 0)
            {
                c_NetCom.CmdLK_C2History(dcode, 1, (byte)type, MySql.DateTimeToTime_t(stime), MySql.DateTimeToTime_t(etime));
            }
        }
    }
}
